package com.springboot.aspect;


import com.springboot.bean.OperationRecord;
import com.springboot.bean.UserInfo;
import com.springboot.mapper.OperationRecordMapper;
import javafx.beans.binding.Bindings;
import org.apache.commons.lang3.ObjectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author zz
 * @version 1.0
 * @Description
 */
@Aspect
@Component
public class InterfaceCallAspect {
    @Autowired
    private OperationRecordMapper operationRecordMapper;
    private static Set<Long> generatedNumbers = new HashSet<>();

    @Around("execution(* com.springboot.service.*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 打印方法入参
        System.out.println("调用方法：" + joinPoint.getSignature().getName() + "，入参为：");
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println(arg);
        }
        long startTime = System.currentTimeMillis();
        try {
            Object result = joinPoint.proceed();
            // 打印方法出参
            System.out.println("方法：" + joinPoint.getSignature().getName() + "，出参为：" + result);
            // 记录用户操作记录
            OperationRecord operationRecord = new OperationRecord();
            if(ObjectUtils.isNotEmpty(args) && args[0] instanceof UserInfo){
                operationRecord.setUserId(((UserInfo) args[0]).getId());
            }else {
                operationRecord.setUserId(generateUniqueRandomLong());
            }
            operationRecord.setInterfaceName(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            operationRecord.setOperationTime(new Date());
            operationRecordMapper.insertOperationRecord(operationRecord);
            return result;

        } finally {
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            // 打印方法耗时
            System.out.println("方法：" + joinPoint.getSignature().getName() + " 执行耗时：" + duration + " 毫秒");
        }
    }

    public static long generateUniqueRandomLong() {
        long randomPart;
        long timestamp = System.currentTimeMillis();
        do {
            // 生成一个随机的部分
            randomPart = ThreadLocalRandom.current().nextLong();
            // 结合时间戳和随机部分生成一个尽量唯一的数
            long combined = timestamp + randomPart;
            if (generatedNumbers.add(combined)) {
                return combined;
            }
        } while (true);
    }
}
